package com.apes.framework.plugin.workflow;

import com.alibaba.fastjson.JSON;
import com.apes.framework.api.DomainService;
import com.apes.framework.jpa.repository.CustomRepository;
import com.apes.framework.plugin.workflow.parser.model.Node;
import com.apes.framework.plugin.workflow.parser.model.Workflow;
import com.apes.framework.util.JpaUtil;
import com.apes.framework.util.MapUtil;
import com.apes.framework.util.Tools;
import com.apes.scm.rbac.model.User;
import com.apestech.api.workflow.WorkFlow;
import com.apestech.framework.util.StringUtil;
import org.flowable.bpmn.model.BpmnModel;
import org.flowable.engine.*;
import org.flowable.engine.history.HistoricProcessInstance;
import org.flowable.engine.impl.RepositoryServiceImpl;
import org.flowable.engine.impl.persistence.entity.ProcessDefinitionEntity;
import org.flowable.engine.repository.ProcessDefinition;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.identitylink.api.IdentityLink;
import org.flowable.task.api.Task;
import org.flowable.task.api.TaskInfo;
import org.flowable.task.api.history.HistoricTaskInstance;
import org.flowable.task.service.impl.persistence.entity.TaskEntity;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageImpl;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;


/**
 * 功能：flowable实现
 *
 * @author xul
 * @create 2017-12-21 9:04
 */
@Service
public class FlowableEngine extends DomainService implements WorkflowEngine {
    private static final String wf_content = "wf_content";
    private static final String wf_variable_prefix = "wf_variable_";

    @Autowired
    private ProcessEngine engine;

    /**
     * 功能：流程启动
     *
     * @param processDefinitionKey 工作流ID
     * @param variables            变量列表
     * @return 工作流实例编号
     */
    @Override
    public String startProcessInstanceById(String processDefinitionKey, Map variables) {
        Workflow wf = getWorkflow(processDefinitionKey);
        Node start = wf.getStartNode();

        //第一步：Mapping
        Map mv = mapping(start, variables);
        Object processInitiator = Tools.isNull(mv.get("processInitiator")) ? variables.get("processInitiator") : mv.get("processInitiator");
        if (Tools.isNull(processInitiator)) {
            throw new RuntimeException("流程发起人不允许为空！");
        }
        mv.put("processInitiator", processInitiator); //流程发起人
        mv.put("processInitiatingDepartment", Tools.isNull(mv.get("processInitiatingDepartment")) ? variables.get("processInitiatingDepartment") : mv.get("processInitiatingDepartment")); //流程发起部门
        mv.put("taskExecutorPost", Tools.isNull(mv.get("processInitiatingPost")) ? variables.get("processInitiatingPost") : mv.get("processInitiatingPost")); //流程发起岗位

        Object taskExecutor = Tools.isNull(mv.get("taskExecutor")) ? variables.get("taskExecutor") : mv.get("taskExecutor");
        if (Tools.isNull(taskExecutor)) {
            throw new RuntimeException("任务执行人不允许为空！");
        }
        mv.put("taskExecutor", taskExecutor); //最后执行人
        mv.put("taskExecutorDepartment", Tools.isNull(mv.get("taskExecutorDepartment")) ? variables.get("taskExecutorDepartment") : mv.get("taskExecutorDepartment")); //最后执行部门
        mv.put("taskExecutorPost", Tools.isNull(mv.get("taskExecutorPost")) ? variables.get("taskExecutorPost") : mv.get("taskExecutorPost")); //最后执行岗位

        if (start.getContent() != null) {
            Map m = content(start, variables);
            if (m.size() != 0) mv.put(wf_content, JSON.toJSONString(m));
        }

        //第二步：启动流程实例
        ProcessInstance pi = getRuntimeService().startProcessInstanceByKey(processDefinitionKey, getBusinessKey(variables, mv), mv);

        //第三步：业务逻辑处理
        start.getEsbIds().stream().forEach(esbId -> {
            invoke(esbId, variables);
        });

        //第四步：下一步任务前置处理
        executePreTask(wf, pi.getProcessInstanceId(), variables);

//        BpmnModel bpmnModel = getBpmnModelByDefinitionId(pi.getProcessDefinitionId());
//        System.out.println(bpmnModel);

//        getRuntimeService().deleteProcessInstance(pi.getId(), "test");

        sendSynEvent("event:wf.processInstanceExt.create", mapper(
                "processInstanceId", pi.getId(),
                "businessType", variables.get("innerBusinessType"),
                "businessKey", pi.getBusinessKey(),
                "processInitiator", processInitiator,
                "processInitiatingDepartment", mv.get("processInitiatingDepartment")
        ));

        return pi.getId();
    }

    /**
     * 功能：执行任务
     *
     * @param taskId    任务ID
     * @param variables 输入参数
     */
    @Override
    public void executeTask(String taskId, Map variables) {
        Task task = findTaskById(taskId);
        executeTask(task, variables);
    }

    /**
     * 功能：执行任务
     *
     * @param task      任务
     * @param variables 输入参数
     */
    private void executeTask(Task task, Map variables) {
        ProcessInstance pi = findProcessInstanceById(task.getProcessInstanceId());
        Workflow wf = getWorkflow(pi.getProcessDefinitionKey());
        Node node = wf.getTaskNode(task.getTaskDefinitionKey());

        //第一步：Mapping
        Map mv = mapping(node, variables);

        //第二步：执行任务
        List<String> users = new ArrayList<>();
        if (!node.isAutomatic()) {
            Object taskExecutor = Tools.isNull(mv.get("taskExecutor")) ? variables.get("taskExecutor") : mv.get("taskExecutor");
            if (Tools.isNull(taskExecutor)) {
                throw new RuntimeException("任务执行人不允许为空！");
            }
            mv.put("taskExecutor", taskExecutor); //最后执行人
            mv.put("taskExecutorDepartment", Tools.isNull(mv.get("taskExecutorDepartment")) ? variables.get("taskExecutorDepartment") : mv.get("taskExecutorDepartment")); //最后执行部门
            mv.put("taskExecutorPost", Tools.isNull(mv.get("taskExecutorPost")) ? variables.get("taskExecutorPost") : mv.get("taskExecutorPost")); //最后执行岗位

            users = getTaskUser(task);
            if (StringUtil.isNotEmpty(task.getAssignee())) {
                claim(task.getId(), String.valueOf(taskExecutor)); //任务签收
            }
        }

        /**设置网关变量**/
        String variableName = getExclusiveGatewayVariableName(task.getId());
        if (!StringUtils.isEmpty(variableName)) {
            String field = wf_variable_prefix + variableName;
            if (variables.containsKey(field) || variables.containsKey(variableName)) {
                getTaskService().setVariableLocal(task.getId(), variableName,
                        variables.get(field) != null ? variables.get(field) : variables.get(variableName));
                mv.put(variableName, variables.get(field) != null ? variables.get(field) : variables.get(variableName));
            }
        }

        getTaskService().complete(task.getId(), mv);

        //第三步：业务逻辑执行
        node.getAfterEsbIds().stream().forEach(esbId -> {
            invoke(esbId, variables);
        });

        users.stream().distinct().forEach(userId -> {
            sendAynEvent("event:ws.wf.task", mapper("action", "executeTask", "userId", userId, "taskId", task.getId(), "task", convertTask(task)));
        });

        //第四步：下一步任务前置处理
        executePreTask(wf, pi.getProcessInstanceId(), variables);
    }


    /**
     * 功能：查询待办列表
     *
     * @param userId
     * @return
     */
    @Override
    public List<Map> getTasks(String userId) {
        List<Map> result = new ArrayList<>();
        getTaskService().createTaskQuery().taskCandidateOrAssigned(userId).active().orderByTaskCreateTime().asc().list().stream()
                .map(task -> {
                    Map m = convertTask(task);
                    WorkFlow work;
                    try {
                        work = new WorkFlow(engine);
                        m.put("createTime", work.getTaskUpdateTime(task, userId));
                    } catch (Exception e) {
                        m.put("createTime", task.getCreateTime());
                    }
                    Map topic;
                    try {
                        topic = result.stream().filter(row -> row.get("title").toString().equalsIgnoreCase(m.get("processDefinitionName").toString())).findFirst().get();
                    } catch (Exception e) {
                        topic = new HashMap();
                        topic.put("title", m.get("processDefinitionName"));
                        topic.put("list", new ArrayList());
                        result.add(topic);
                    }
                    ((List) topic.get("list")).add(m);

                    return m;
                }).count();
        return result;
    }

    /**
     * 功能：查询待办列表
     *
     */
    @Override
    public List<Map> getTasks(String userId, int page, int size) {
        List<Task> tasks = getTaskService().createTaskQuery().taskCandidateOrAssigned(userId).active().orderByTaskCreateTime().asc().list();
        PageImpl<Map> r = paged(tasks, page, size, task1 -> {
            Task task = (Task) task1;
            Map m = convertTask(task);
            try {
                WorkFlow work = new WorkFlow(engine);
                m.put("createTime", work.getTaskUpdateTime(task, userId));
            } catch (Exception e) {
                m.put("createTime", task.getCreateTime());
            }
            return m;
        });
        return r.getContent();
    }

    public Map getTaskByTaskId(String taskId) {
        List<Task> list = getTaskService().createTaskQuery().active().taskId(taskId).list();
        if (list.size() > 0) {
            return convertTask(list.get(0));
        } else {
            throw new RuntimeException("未找到对应的代办信息，或该代办已挂起，任务编码：" + taskId);
        }
    }

    private Map convertTask(Task task) {
        Map m = new HashMap();
        m.put("taskId", task.getId());
        m.put("taskName", task.getName());

        Map content = new LinkedHashMap();
        Object o = getVariable(task.getId(), wf_content);
        if (!Tools.isNull(o)) {
            content.putAll(JSON.parseObject((String) o));
        }
        m.put("content", content);

        m.put("createTime", task.getCreateTime());
        String processDefinitionKey = null;
        Object pi = findProcessInstance(task.getProcessInstanceId());
        if (pi instanceof HistoricProcessInstance) {
            m.put("processDefinitionName", ((HistoricProcessInstance) pi).getProcessDefinitionName());
            m.put("businessKey", ((HistoricProcessInstance) pi).getBusinessKey());
            processDefinitionKey = ((HistoricProcessInstance) pi).getProcessDefinitionKey();
        } else if (pi instanceof ProcessInstance) {
            m.put("processDefinitionName", ((ProcessInstance) pi).getProcessDefinitionName());
            m.put("businessKey", ((ProcessInstance) pi).getBusinessKey());
            processDefinitionKey = ((ProcessInstance) pi).getProcessDefinitionKey();
            m.put("exclusiveGateway", getExclusiveGateway(task.getId()));
        }
        Workflow wf = getWorkflow(processDefinitionKey);

        Node node = wf.getTaskNode(task.getTaskDefinitionKey());
        if (node != null) {
            m.put("formId", node.getForm().getId());
            m.put("api", node.getForm().getApi());
            m.put("fields", node.getFields());
            m.put("auth", node.getAuth());
            m.put("editable", node.isEditable());

            // 抄送流程发起人
            if (node.isCarbonCopy()) {
                String processInitiator = (String) engine.getTaskService().getVariable(task.getId(), "processInitiator");
                List<Object> users = sendSynEvent("event:aut.user.findOne", MapUtil.mapper("id", Integer.parseInt(processInitiator)));
                if (users != null && users.size() > 0 && users.get(0) != null) {
                    m.put("carbonCopy", MapUtil.mapper(
                            "id", ((User) users.get(0)).getId(),
                            "name", ((User) users.get(0)).getName()
                            )
                    );
                }
            }
        }
        return m;
    }

    /**
     * 功能：取下一步任务的排它网关信息
     *
     * @param taskId
     * @return
     */
    @Override
    public List getExclusiveGateway(String taskId) {
        try {
            WorkFlow flow = new WorkFlow(engine);
            List rows = flow.getDecision(taskId);
            if (rows == null) rows = new ArrayList();
            return rows;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    private String getExclusiveGatewayVariableName(String taskId) {
        List<Map> rows = getExclusiveGateway(taskId);
        if (rows.isEmpty()) return null;
        return (String) rows.stream().findFirst().get().get("valueId");
    }

    /**
     * 功能：查询待办列表
     *
     * @param userId
     * @return
     */
    @Override
    public Long getTaskCount(String userId) {
        return getTaskService()
                .createTaskQuery()
                .taskCandidateOrAssigned(userId)
                .active()
                .count();
    }

    /**
     * 功能：下一步任务前置处理
     *
     * @param wf
     * @param processInstanceId
     * @param variables
     */
    private void executePreTask(Workflow wf, String processInstanceId, Map variables) {
        //第一步：获取下步节点
        // 非结束任务
        //第二步：任务分配
        // 或 子流程
        //第二步：子流程执行
        // 或 结束任务
        //第二步：结束任务

        //第一步：获取下步节点
        Task task = getNextTask(processInstanceId);
        if (task != null) {
            //第二步：任务分配
            Node next = wf.getTaskNode(task.getTaskDefinitionKey());
            if (next == null) throw new RuntimeException("任务节点：" + task.getTaskDefinitionKey() + " 没有配置！");


            // 保证前置ESB被执行
            next.getBeforeEsbIds().stream().forEach(esbId -> {
                invoke(esbId, variables);
            });


            if (next.isAutomatic()) {
                extendVariables(variables);
                executeTask(task, variables);
                return;
            }

            List<String> users = new ArrayList<>();
            Map mv = mapping(next, variables);
            if (!Tools.isNull(mv.get("assignee"))) { //业务数据中指定受理人
                String userId = (String) mv.get("assignee");
                users.add(userId);
            } else if (!Tools.isNull(mv.get("candidates"))) { //业务数据中指定候选人
                List candidates = JSON.parseArray((String) mv.get("candidates"));
                candidates.stream().forEach(userId -> users.add(String.valueOf(userId)));
            } else {
                String processInitiatingDepartment;
                if (!Tools.isNull(mv.get("processInitiatingDepartment"))) {
                    processInitiatingDepartment = (String) mv.get("processInitiatingDepartment");
                } else {
                    processInitiatingDepartment = (String) getTaskService().getVariable(task.getId(), "processInitiatingDepartment");
                }
                String taskExecutorPost = (String) getTaskService().getVariable(task.getId(), "taskExecutorPost");
                List<Map> rows = next.getUsers(variables, processInitiatingDepartment, taskExecutorPost);
                if (rows.isEmpty()) {
                    throw new RuntimeException("任务节点：【" + task.getTaskDefinitionKey() + "：" + task.getName() + "】 没有办理人！");
                }
                users.addAll(rows.stream().distinct().map(new Function<Map, String>() {
                    @Override
                    public String apply(Map user) {
                        return user.get("id").toString();
                    }
                }).collect(Collectors.toList()));
            }
            users.stream().distinct().forEach(userId -> {
                if (users.size() == 1) getTaskService().setAssignee(task.getId(), userId); //指定受理人
                else getTaskService().addCandidateUser(task.getId(), userId); //指定候选人
                sendAynEvent("event:ws.wf.task", mapper("action", "executePreTask", "userId", userId, "taskId", task.getId(), "task", convertTask(task)));
            });

            if (next.getContent() != null) {
                Map m = content(next, variables);
                if (m.size() != 0) getTaskService().setVariableLocal(task.getId(), wf_content, JSON.toJSONString(m));
            }

        } else {
            //执行结束任务
            Node end = wf.getEndNode();
            if (end != null) {
                //业务逻辑处理
                end.getEsbIds().stream().forEach(esbId -> {
                    invoke(esbId, variables);
                });
            }
        }
    }

    private void extendVariables(Map variables) {
        if (!variables.containsKey("innerBusinessType") || !variables.containsKey("innerBusinessKey")) return;
        Class clazz = JpaUtil.getDomainClass((String) variables.get("innerBusinessType"));
        if (clazz == null) return;
        CustomRepository repository = JpaUtil.getRepository(clazz.getName());
        if (repository == null) return;
        Object source = repository.findOne(JpaUtil.getId((String) variables.get("innerBusinessType"), (String) variables.get("innerBusinessKey")));
        if (source == null) return;
        Map m = MapUtil.mapped(source);
        m.forEach((k, v) -> variables.put(k, v));
    }

    /**
     * 功能：获取流程下步待执行任务
     *
     * @param processInstanceId
     * @return
     */
    private Task getNextTask(String processInstanceId) {
        return getTaskService().createTaskQuery().processInstanceId(processInstanceId).singleResult();
    }

    /**
     * 功能：获取业务单号
     *
     * @param variables
     * @param mv
     * @return
     */
    private String getBusinessKey(Map variables, Map mv) {
        Object businessKey = null;
        if (mv != null) {
            if (mv.containsKey("businessKey")) businessKey = mv.get("businessKey");
            if (businessKey == null && mv.containsKey("id")) businessKey = mv.get("id");
        }
        if (businessKey == null && variables.containsKey("id")) businessKey = variables.get("id");
        if (Tools.isNull(businessKey)) throw new RuntimeException("业务单号不允许为空！");
        return String.valueOf(businessKey);
    }

    /**
     * 功能：mapping
     *
     * @param node
     * @param variables
     * @return
     */
    private Map mapping(Node node, Map variables) {
        Map m = null;
        if (node != null) m = node.convert(variables);
        if (m == null) m = new HashMap();
        return m;
    }

    /**
     * 功能：content
     *
     * @param node
     * @param variables
     * @return
     */
    private Map content(Node node, Map variables) {
        Map m = null;
        if (node != null) m = node.content(variables);
        if (m == null) m = new HashMap();
        return m;
    }

    /**
     * 功能：获取Workflow元模型
     *
     * @param processDefinitionKey
     * @return
     */
    private Workflow getWorkflow(String processDefinitionKey) {
        Workflow wf = Workflow.getWorkflow(processDefinitionKey);
        if (wf == null) throw new RuntimeException("流程：" + processDefinitionKey + " 没有配置！");
        return wf;
    }

    /**
     * 功能：获取任务的受理人
     *
     * @param task
     * @return
     */
    private String getTaskAssignee(Task task) {
        if (!Tools.isNull(task.getAssignee())) return task.getAssignee();
        return null;
    }

    /**
     * 功能：获取任务的候选人列表
     */
    private List<String> getTaskCandidate(String taskId) {
        List<String> users = new ArrayList<>();
        List identityLinkList = getTaskService().getIdentityLinksForTask(taskId);
        if (identityLinkList == null) return users;
        for (Iterator iterator = identityLinkList.iterator(); iterator.hasNext(); ) {
            IdentityLink identityLink = (IdentityLink) iterator.next();
            if (identityLink.getUserId() != null) {
                users.add(identityLink.getUserId());
            }
        }
        return users;
    }

    /**
     * 功能：获取流程任务组件
     *
     * @return TaskService
     */
    private TaskService getTaskService() {
        return engine.getTaskService();
    }

    /**
     * 功能：获取运行时服务组件
     *
     * @return RuntimeService
     */
    private RuntimeService getRuntimeService() {
        return engine.getRuntimeService();
    }

    /**
     * 功能：获取历史服务组件
     *
     * @return HistoryService
     */
    private HistoryService getHistoryService() {
        return engine.getHistoryService();
    }

    /**
     * 功能：获取流程存储服务组件
     *
     * @return RepositoryService
     */
    private RepositoryService getRepositoryService() {
        return engine.getRepositoryService();
    }

    /**
     * 功能：1、认领
     * 2、转办（直接将办理人assignee 换成别人，这时任务的拥有着不再是转办人，而是为空，相当与将任务转出）
     *
     * @param taskId 任务ID
     * @param userId 被转办人
     */
    private void setAssignee(String taskId, String userId) throws Exception {
        getTaskService().setAssignee(taskId, userId);
    }

    /**
     * 功能：签收
     *
     * @param taskId
     * @param userId
     */
    private void claim(String taskId, String userId) {
        getTaskService().claim(taskId, userId);
    }


    /**
     * 根据任务ID获得任务实例
     *
     * @param taskId 任务ID
     * @return
     * @throws Exception
     */
    private TaskEntity findTaskById(String taskId) {
        TaskEntity task = (TaskEntity) getTaskService().createTaskQuery().taskId(taskId).singleResult();
        if (task == null) {
            throw new RuntimeException("任务实例未找到!");
        }
        return task;
    }

    /**
     * 根据任务ID获得历史任务实例
     *
     * @param taskId 任务ID
     * @return
     * @throws Exception
     */
    private HistoricTaskInstance findHistoricTaskById(String taskId) {
        HistoricTaskInstance task = getHistoryService().createHistoricTaskInstanceQuery().taskId(taskId).singleResult();
        if (task == null) {
            throw new RuntimeException("任务实例未找到!");
        }
        return task;
    }

    /**
     * 根据任务ID获得任务信息
     *
     * @param taskId
     * @return
     */
    private TaskInfo findTaskInfoById(String taskId) {
        TaskInfo taskInfo = getTaskService().createTaskQuery().taskId(taskId).singleResult();
        if (taskInfo == null) {
            taskInfo = getHistoryService().createHistoricTaskInstanceQuery().taskId(taskId).singleResult();
            if (taskInfo == null) {
                throw new RuntimeException("任务实例未找到!");
            }
        }
        return taskInfo;
    }

    /**
     * 根据任务ID获取对应的流程实例
     *
     * @param taskId 任务ID
     * @return
     * @throws Exception
     */
    private ProcessInstance findProcessInstanceByTaskId(String taskId) {
        ProcessInstance processInstance = getRuntimeService().createProcessInstanceQuery()
                .processInstanceId(findTaskById(taskId).getProcessInstanceId()).singleResult();
        if (processInstance == null) {
            throw new RuntimeException("流程实例未找到!");
        }
        return processInstance;
    }

    private Object findProcessInstance(String processInstanceId) {
        Object processInstance = getRuntimeService().createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
        if (processInstance == null) {
            processInstance = getHistoryService().createHistoricProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
            if (processInstance == null) {
                throw new RuntimeException("流程实例未找到!");
            }
        }
        return processInstance;
    }

    /**
     * 根据流程实例ID获取对应的流程实例
     *
     * @param processInstanceId
     * @return
     * @throws Exception
     */
    private ProcessInstance findProcessInstanceById(String processInstanceId) {
        ProcessInstance processInstance = getRuntimeService().createProcessInstanceQuery()
                .processInstanceId(processInstanceId).singleResult();
        if (processInstance == null) {
            throw new RuntimeException("流程实例未找到!");
        }
        return processInstance;
    }

    private HistoricProcessInstance findHistoricProcessInstanceById(String processInstanceId) {
        HistoricProcessInstance processInstance = getHistoryService().createHistoricProcessInstanceQuery()
                .processInstanceId(processInstanceId).singleResult();
        if (processInstance == null) {
            throw new RuntimeException("流程实例未找到!");
        }
        return processInstance;
    }

    private Object getVariable(String taskId, String variableName) {
        Object result = null;
        TaskInfo taskInfo = findTaskInfoById(taskId);
        if (taskInfo instanceof Task) {
            result = getTaskService().getVariable(taskId, variableName);
            if (result == null) result = getTaskService().getVariableLocal(taskId, variableName);
        } else {
            result = taskInfo.getProcessVariables().get(variableName);
            if (result == null) result = taskInfo.getTaskLocalVariables().get(variableName);
        }
        return result;
    }

    private List<String> getTaskUser(Task task) {
        List<String> users = new ArrayList<>();
        if (StringUtil.isNotEmpty(task.getAssignee())) {
            users.add(task.getAssignee());
        } else {
            users.addAll(getTaskCandidate(task.getId()));
        }
        return users;
    }

    /**
     * 根据一个流程实例id挂起该流程实例
     *
     * @param processInstanceId
     */
    @Override
    public void suspendProcessInstanceById(String processInstanceId) {
        Task task = getNextTask(processInstanceId);
        List<String> users = getTaskUser(task);
        getTaskService().setVariableLocal(task.getId(), "suspendDate", new Date());
        getRuntimeService().suspendProcessInstanceById(processInstanceId);
        users.stream().forEach(userId -> {
            sendAynEvent("event:ws.wf.task", mapper("action", "executeTask", "userId", userId, "taskId", task.getId(), "task", convertTask(task)));
        });
    }

    /**
     * 根据一个流程实例id激活该流程实例
     *
     * @param processInstanceId
     */
    @Override
    public void activateProcessInstanceById(String processInstanceId) {
        Task task = getNextTask(processInstanceId);
        List<String> users = getTaskUser(task);
        getRuntimeService().activateProcessInstanceById(processInstanceId);
        getTaskService().setVariableLocal(task.getId(), "activateDate", new Date());
        users.stream().forEach(userId -> {
            sendAynEvent("event:ws.wf.task", mapper("action", "executePreTask", "userId", userId, "taskId", task.getId(), "task", convertTask(task)));
        });
    }

    private BpmnModel getBpmnModelByDefinitionId(String processDefinitionId) {
        BpmnModel bpmnModel = getRepositoryService().getBpmnModel(processDefinitionId);
        return bpmnModel;
    }

    /**
     * 根据任务ID获取流程定义
     *
     * @param taskId 任务ID
     * @return
     * @throws Exception
     */
    private ProcessDefinitionEntity getProcessDefinitionEntityByTaskId(String taskId) {
        ProcessDefinitionEntity processDefinition = (ProcessDefinitionEntity) ((RepositoryServiceImpl) getRepositoryService())
                .getDeployedProcessDefinition(findTaskById(taskId).getProcessDefinitionId());
        if (processDefinition == null) {
            throw new RuntimeException("流程定义未找到!");
        }
        return processDefinition;
    }

    private ProcessDefinition getProcessDefinitionById(String processDefinitionId) {
        ProcessDefinition processDefinition = getRepositoryService().getProcessDefinition(processDefinitionId);
        return processDefinition;
    }

}
